﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace lhhp.net.Utility
{
    public class DataTableUtility
    {
        public static DataTable Join(DataTable First, DataTable Second, DataColumn[] FJC, DataColumn[] SJC, bool isLeftJoin)
        {
            DataTable table = new DataTable("Join");
            using (DataSet ds = new DataSet())
            {
                ds.Tables.AddRange(new DataTable[] { First.Copy(), Second.Copy() });
                //Identify Joining Columns from First
                DataColumn[] parentcolumns = new DataColumn[FJC.Length];
                for (int i = 0; i < parentcolumns.Length; i++)
                {
                    parentcolumns[i] = ds.Tables[0].Columns[FJC[i].ColumnName];
                }
                DataColumn[] childcolumns = new DataColumn[SJC.Length];
                for (int i = 0; i < childcolumns.Length; i++)
                {
                    childcolumns[i] = ds.Tables[1].Columns[SJC[i].ColumnName];
                }
                DataRelation r = new DataRelation(string.Empty, parentcolumns, childcolumns, false);
                ds.Relations.Add(r);
                //Create Columns for JOIN table
                for (int i = 0; i < First.Columns.Count; i++)
                {
                    table.Columns.Add(First.Columns[i].ColumnName, First.Columns[i].DataType);
                }
                for (int i = 0; i < Second.Columns.Count; i++)
                {
                    //Beware Duplicates 
                    if (!table.Columns.Contains(Second.Columns[i].ColumnName))
                    {
                        table.Columns.Add(Second.Columns[i].ColumnName, Second.Columns[i].DataType);
                    }
                    else
                    {
                        table.Columns.Add(Second.Columns[i].ColumnName + "_Second", Second.Columns[i].DataType);
                    }
                }
                // 第一个表开始循环
                table.BeginLoadData();
                foreach (DataRow firstrow in ds.Tables[0].Rows)
                {
                    DataRow[] childrows = firstrow.GetChildRows(r);
                    if (childrows != null && childrows.Length > 0)
                    {
                        object[] parentarray = firstrow.ItemArray;
                        foreach (DataRow secondrow in childrows)
                        {
                            object[] secondarray = secondrow.ItemArray;

                            object[] joinarray = new object[parentarray.Length + secondarray.Length];


                            Array.Copy(parentarray, 0, joinarray, 0, parentarray.Length);

                            Array.Copy(secondarray, 0, joinarray, parentarray.Length, secondarray.Length);

                            table.LoadDataRow(joinarray, true);
                        }
                    }
                    else
                    {
                        if (isLeftJoin)
                        {
                            object[] parentarray = firstrow.ItemArray;
                            table.LoadDataRow(parentarray, true);
                        }
                    }
                }
                table.EndLoadData();
            }
            return table;
        }

        public static DataTable Join(DataTable First, DataTable Second, DataColumn FJC, DataColumn SJC)
        {
            return Join(First, Second, new DataColumn[] { FJC }, new DataColumn[] { SJC }, false);
        }

        public static DataTable Join(DataTable First, DataTable Second, string FJC, string SJC)
        {
            return Join(First, Second, new DataColumn[] { First.Columns[FJC] }, new DataColumn[] { Second.Columns[SJC] }, false);
        }

        public static DataTable LeftJoin(DataTable leftTable, DataTable rightTable, string FJC, string SJC)
        {
            return Join(leftTable, rightTable, new DataColumn[] { leftTable.Columns[FJC] }, new DataColumn[] { rightTable.Columns[SJC] }, true);
        }
        public static DataTable LeftJoin(DataTable leftTable, DataTable rightTable, DataColumn FJC, DataColumn SJC)
        {
            return Join(leftTable, rightTable, new DataColumn[] { FJC }, new DataColumn[] { SJC }, true);
        }
    }
}
